package bqds

import (
	"encoding/json"
	"strings"
	"time"

	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
)

func (pd *PgDb) Start(b_inidb bool) {
	if b_inidb {
		logrus.Info("exec InitPgDb...")
		go InitPgDB("sql.yml", pd.Db)
	}
	tradingDay, _ := pd.cr.Rdb.HGet(pd.redisCtxt, "tradingday", "curday").Result()
	preDay := tradingDay
	pd.GetMainIID()
	go pd.OnTick()
	go pd.OnAcc()
	go pd.OnReqLoadTick()

	logrus.Info(tradingDay)
	tick := time.NewTicker(1 * time.Minute)
	pd.savedBar = false
	// logrus.Info("pd.savedBar=",pd.savedBar)
	for range tick.C {
		tradingDay, _ = pd.cr.Rdb.HGet(pd.redisCtxt, "tradingday", "curday").Result()

		if strings.Compare(preDay, tradingDay) != 0 {
			logrus.Info("new trading day:", preDay, "->", tradingDay)
			pd.savedBar = false
			preDay = tradingDay
		}
		hour := time.Now().Local().Hour()
		minute := time.Now().Local().Minute()
		if minute%15 == 0 {
			logrus.Info("hour:minute=", hour, ":", minute, "savedBar=", pd.savedBar)
		}
		if hour == 15 && minute == 30 {
			pd.savedBar = true
			if err := pd.InsertBarFromRedis(); err != nil {
				logrus.Info("pd.InsertBarFromRedis() error:", err)
				// pd.savedBar = false
			}

		}
		// logrus.Info("pd.savedBar=",pd.savedBar,(hour == 15 && minute > 15 || hour > 15) && !pd.savedBar)
		if !pd.savedBar {
			pd.savedBar = true
			if err := pd.InsertBarFromRedis(); err != nil {
				logrus.Info("pd.InsertBarFromRedis() error:", err)
				// pd.savedBar = false
			}

		}
	}

}

func (pd *PgDb) InsertBarFromRedis() error {

	logrus.Infoln("save bar to postgressql from redis(InsertBarFromRedis).....")
	// 取所有 key
	var bars = make([]*Bar, 0)
	rdb := pd.cr.Rdb
	ctx := pd.redisCtxt
	gormPg := pd.GORMpg
	insts, err := rdb.Keys(ctx, "*").Result()
	if err != nil {
		return errors.Wrap(err, "get redis keys")
	}
	// 按合约key入库
	times := 0
	for _, inst := range insts {
		if inst == "tradingday" {
			continue
		}
		var mins = []string{}
		if mins, err = rdb.LRange(ctx, inst, 0, -1).Result(); err != nil {
			logrus.Error("取redis数据错误:", inst, err)
			continue
		}

		for _, bsMin := range mins {
			var bar Bar
			if err = json.Unmarshal([]byte(bsMin), &bar); err != nil {
				logrus.Error("解析bar错误:", bar, " ", err)
				continue
			}
			// logrus.Info("bar=", bar)
			bars = append(bars, &bar)
			if len(bars) >= 2000 { // 10W
				times += 1
				err = gormPg.CreateInBatches(bars, 100).Error
				if err != nil {
					// return errors.Wrap(err, "create batch")
					logrus.Info("error:", err)
				}
				logrus.Info("save bar to pg:", len(bars), "X", times)
				bars = make([]*Bar, 0)
			}
		}
	}
	err = gormPg.CreateInBatches(bars, 2000).Error
	if err != nil {
		return errors.Wrap(err, "create batch")
	}
	logrus.Info("save bar to pg:", len(bars))
	return err
}
